package com.mdc.mansion.api.web.modules.order;

import java.io.IOException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.mdc.mansion.api.web.common.interceptor.NoLoginCheck;
import com.mdc.mansion.api.web.common.web.BaseController;
import com.mdc.mansion.common.exception.BusinessException;
import com.mdc.mansion.common.response.Result;
import com.mdc.mansion.common.response.ResultCode;
import com.mdc.mansion.common.util.I18nUtil;
import com.mdc.mansion.common.util.StringUtils;
import com.mdc.mansion.core.common.util.MapUtils;
import com.mdc.mansion.core.common.util.RestaurantSupport;
import com.mdc.mansion.core.modules.order.RestaurantOrderService;
import com.mdc.mansion.core.modules.pay.dto.AltoPayQryResult;
import com.mdc.mansion.core.modules.pay.dto.AltoRefundQryResult;
import com.mdc.mansion.dataaccess.common.context.ContextHolder;
import com.mdc.mansion.dataaccess.modules.order.entity.RestaurantOrder;
import com.mdc.mansion.dataaccess.modules.order.vo.RestaurantOrderVo;
import com.mdc.mansion.dataaccess.modules.restaurant.entity.Restaurant;

/**
 * 
 * @author xizf
 *
 */
@Controller
@RequestMapping(value = "${adminPath}/bill")
public class RestaurantBillController extends BaseController {
	private final static Logger logger = LoggerFactory.getLogger(RestaurantBillController.class);
	
	
    @Resource
	private RestaurantOrderService restaurantOrderService;
	
	
	
    /**
	 * 账单结账查询，处理流程
	 * 1、根据餐桌、订单号获取订单下菜品
	 * 2、对于有没有完成的菜品需提示是否退菜
	 * 3、根据菜品计算出整个账单金额及优惠金额
	 * 4、叠加服务费、打折等费用计算最终金额，根据页面计算更新数据库数据
	 * 反馈结算界面格式:
	 * 
	 * 2018年1月21日 18:39:23 
	 * 功能修改为根据订单ID查询订单详细情况
	 * 
	 * @author xizf
	 * @date 2018年1月15日 17:38:10
	 * @return
	 */
	@RequestMapping(value = "/QueryByOrder",method  = RequestMethod.POST)
	public Result QueryByOrder(String data)
	{
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
		RestaurantOrderVo restaurantOrderVo = null;
		Map<String,Object> resultMap = null;
		restaurantOrderVo = new RestaurantOrderVo();
		restaurantOrderVo.setRestaurantId(ContextHolder.currentRestaurant().getId());
			/**订单号**/
		restaurantOrderVo.setId(net.sf.json.JSONObject.fromObject(data).getString("orderId"));
		
		resultMap = restaurantOrderService.queryByOrder(restaurantOrderVo);
		if( null == resultMap || 0 == resultMap.size())
		{
			/** 未查询到订单信息 **/
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
			throw new BusinessException(I18nUtil.getMessage("order.query.null.exception"));
		}
		restultResult.setResultMap(resultMap);
	
		return restultResult;
	}
	
	
	/**
	 * 	 * 对账单进行结账处理
	 * 	 * 需传入参数:处理人员，折扣，减免金额，服务费，服务费率、应收金额，实收金额，找零金额
	 * 	 * 处理过程: 对账单下每个产品进行状态变更，变更为已经完成。对订单本身进行数据更新和状态变更
	 * @param data
	 * @return
	 */
	@RequestMapping(value = "/submit",method  = RequestMethod.POST)
	public Result billCheckOut(String data)
	{
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
		Restaurant restaurant = ContextHolder.currentRestaurant();
		
		RestaurantOrder restaurantOrder = null;
		restaurantOrder = JSONObject.parseObject(data, RestaurantOrder.class);
		restaurantOrder.setCashierTime(Calendar.getInstance().getTime());
		restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
		restaurantOrder.setRestaurantId(restaurant.getId());
		restaurantOrder.setId(net.sf.json.JSONObject.fromObject(data).getString("restaurantOrderId"));
		
		Map<String,Object> restaurantOrderItemDTOs = restaurantOrderService.billCheckOut(restaurantOrder);
//		restultResult.setProperty("dishesOrderItemList",restaurantOrderItemDTOs.get("dishesOrderItemList"));
		restultResult.setProperty("itemDetailList", restaurantOrderItemDTOs.get("itemDetailList"));
		restultResult.setProperty("totalPrice",restaurantOrderItemDTOs.get("totalPrice"));
		restultResult.setProperty("abatement", restaurantOrderItemDTOs.get("abatement"));
		restultResult.setProperty("servicePrice",restaurantOrderItemDTOs.get("servicePrice"));
		restultResult.setProperty("actualReceivePrice", restaurantOrderItemDTOs.get("actualReceivePrice"));
		restultResult.setProperty("refundPrice",restaurantOrderItemDTOs.get("refundPrice"));
		return restultResult;
	}
	
	@RequestMapping(value = "/prePay",method  = RequestMethod.POST)
	public Result getPayJson(String data) {
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
		Restaurant restaurant = ContextHolder.currentRestaurant();
		RestaurantOrder restaurantOrder = JSONObject.parseObject(data, RestaurantOrder.class);
		restaurantOrder.setCashierTime(Calendar.getInstance().getTime());
		restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
		restaurantOrder.setRestaurantId(restaurant.getId());
		restaurantOrder.setId(net.sf.json.JSONObject.fromObject(data).getString("restaurantOrderId"));
		Map<String,Object> returnMap = null;
		try {
			returnMap = restaurantOrderService.getPayJson(restaurantOrder);
			restultResult.setResultMap(returnMap);
		}catch (Exception e){
			restultResult.setDescription(e.getMessage());
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
		}
		return restultResult;
	}
	
	@NoLoginCheck
	@RequestMapping(value="/payBack", method = { RequestMethod.GET, RequestMethod.POST })
	public void OrderPayBack(HttpServletRequest request, HttpServletResponse response) throws IOException, ParseException {
		try {
			logger.error(">>>>>>>>>>收到支付通知:"+request.getParameter("data"));
			logger.error(">>>>>>>>>>收到支付通知:"+request.getParameter("sign"));
			restaurantOrderService.OrderPayBack(request,response);
		} catch (IOException e) {
			response.setStatus(HttpStatus.SC_BAD_REQUEST);
			response.getOutputStream().write(e.getMessage().getBytes("UTF-8"));
		}
	}
	
	/**
	 * 订单退款
	 * @param data
	 * @return
	 * @author xizf
	 * @date 2018年1月15日 17:38:10
	 */
	@RequestMapping(value = "/refund",method  = RequestMethod.POST)
	public Result refund( String data)throws Exception
	{
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
		Restaurant restaurant = ContextHolder.currentRestaurant();
		RestaurantOrder restaurantOrder = JSONObject.parseObject(data, RestaurantOrder.class);
		restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
		restaurantOrder.setRestaurantId(restaurant.getId());
		restaurantOrder.setSerialNum(net.sf.json.JSONObject.fromObject(data).getString("restaurantOrderId"));
		try {
			restaurantOrderService.refund(restaurantOrder);
		}catch (Exception e){
			restultResult.setDescription(e.getMessage());
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
		}
		return restultResult;
	}
	
	@ResponseBody
	@RequestMapping("preRefund")
	public Result preRefundJson(String data) {
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
		Restaurant restaurant = ContextHolder.currentRestaurant();
		RestaurantOrder restaurantOrder = JSONObject.parseObject(data, RestaurantOrder.class);
		restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
		restaurantOrder.setRestaurantId(restaurant.getId());
		restaurantOrder.setSerialNum(net.sf.json.JSONObject.fromObject(data).getString("restaurantOrderId"));
		try {
			restaurantOrderService.preRefundJson(restaurantOrder);
		} catch (Exception e) {
			restultResult.setDescription(e.getMessage());
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
		}
		return restultResult;
	}
	
	
	@NoLoginCheck
	@RequestMapping(value="/refundBack", method = { RequestMethod.GET, RequestMethod.POST })
	public void OrderRefundBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
		try {
			logger.error(">>>>>>>>>>收到退款通知:"+request.getParameter("data"));
			logger.error(">>>>>>>>>>收到退款通知:"+request.getParameter("sign"));
			restaurantOrderService.OrderRefundBack(request,response);
		} catch (IOException e) {
			response.setStatus(HttpStatus.SC_BAD_REQUEST);
			response.getOutputStream().write(e.getMessage().getBytes("UTF-8"));
		}
	}
	
	/**
	 * 只需订单ID既可
	 * @param data
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/qryPayLog", method = { RequestMethod.POST })
	public Result qryPayLog(String data) throws Exception {
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
		JSONObject json = JSONObject.parseObject(data);
		if(!json.containsKey("out_trade_no") || StringUtils.isBlank(json.getString("out_trade_no"))){
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
			return restultResult;
		}
		
		AltoPayQryResult qryResult = null;
		try {
			qryResult = restaurantOrderService.qryPayLog(data);
		}catch (Exception e){
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
			restultResult.setDescription(e.getMessage());
			return restultResult;
		}
		restultResult.setResultMap(MapUtils.bean2map(qryResult));
		return restultResult;
	}
	
	/**
	 * 只需订单ID既可
	 * @param data
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/qryRefundLog", method = { RequestMethod.POST })
	public Result qryRefundLog(String data) throws Exception {
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
		JSONObject json = JSONObject.parseObject(data);
		if(!json.containsKey("out_trade_no")|| StringUtils.isBlank(json.getString("out_trade_no"))){
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
			return restultResult;
		}
		AltoRefundQryResult qryResult = null;
		try {
			qryResult = restaurantOrderService.qryRefundLog(data);
		}catch (Exception e){
			restultResult.setCode(ResultCode.COMMON_EXCEPTION);
			restultResult.setDescription(e.getMessage());
			return restultResult;
		}
		restultResult.setResultMap(MapUtils.bean2map(qryResult));
		return restultResult;
	}
	

	/**
	 * 	 * 历史订单
	 * 	 * 入参: 餐厅ID,日期(日期只能选择一天,细化到日,格式: YYYYMMDD)
	 * 	 * 出参: 当日收入,昨日收入,选择日期收入
	 * 	 * 选择日期的订单列表，如果是当日显示当日，订单需显示状态
	 * @param data
	 * @return
	 */
	@RequestMapping(value = "/history",method  = RequestMethod.POST)
	public Result history(String data)
	{
		Result restultResult = new Result(ResultCode.COMMON_SUCCESS);
//		Restaurant restaurant = ContextHolder.currentRestaurant();
		Map<String,Object> resultMap = null;
		RestaurantOrderVo restaurantOrderVo = new RestaurantOrderVo();

		restaurantOrderVo.setQueryDate(net.sf.json.JSONObject.fromObject(data).getString("orderDate"));
//		restaurantOrderVo.setRestaurantId("90f106cb4612450d9fdd58f43a44ce12");
		restaurantOrderVo.setRestaurantId(ContextHolder.currentRestaurant().getId());
		
		restaurantOrderVo.setPageSize(net.sf.json.JSONObject.fromObject(data).getString("pageSize"));
		restaurantOrderVo.setPageNo(net.sf.json.JSONObject.fromObject(data).getString("pageNo"));
		resultMap = restaurantOrderService.history(restaurantOrderVo);

		restultResult.setProperty("resultMap", JSONObject.toJSON(resultMap));
		
		return restultResult;
	}
	
	

}
